var STATS = {};
var POS = {'C':2, '1B':3, '2B':4, '3B':5, 'SS':6, 'LF':7, 'CF':8, 
  'RF':9, 'DH':10, 'P':1, 'OF':0};
var POS_GAMP = ['O', null, 2, 3, 4, 5, 6, 7, 8, 9, 'D'];

var lgCodes = {
  'American League':      'A',
  'National League':      'N',
  'Central League':       'C',
  'Pacific League':       'J',
  'International League': 'I',
  'Mexican League':       'M',
  'Pacific Coast League': 'P',
  'Eastern League':       'E', 
  'Southern League':      'S',
  'Texas League':         'T',
  'Atlantic League':      'L'
};

function parseRoster() {
  var i, roster, trs, tds, id;
  trs = document.getElementById('standard_roster').getElementsByTagName(
      'tbody')[0].getElementsByTagName('tr');
      
  STATS.roster = {};
  for (i=0; i<trs.length; i++) {
    roster = {};
    tds = trs[i].getElementsByTagName('td');
    roster.name = tds[0].attributes.csk.textContent;
    id = tds[0].getElementsByTagName('a')[0].href;
    roster.id = id.substring(id.length-12);
    roster.age = +tds[1].textContent || 0;
    roster.b =    tds[2].textContent.trim();
    roster.t =    tds[3].textContent.trim();
    STATS.roster[roster.id] = roster;
  }
  return STATS.roster;
}

function parseBat() {
  var i, bat, trs, tds, id;
  trs = document.getElementById('team_batting').getElementsByTagName(
      'tbody')[0].getElementsByTagName('tr');
      
  for (i=0; i<trs.length; i++) {
    bat = {};
    tds = trs[i].getElementsByTagName('td');
    id = tds[1].getElementsByTagName('a')[0].href;
    id = id.substring(id.length-12);
    bat.g =   +tds[3].textContent.trim();
    bat.ab =  +tds[5].textContent.trim();
    bat.h =   +tds[7].textContent.trim();
    bat.db =  +tds[8].textContent.trim();
    bat.tr =  +tds[9].textContent.trim();
    bat.hr =  +tds[10].textContent.trim();
    bat.rbi = +tds[11].textContent.trim();
    bat.sb =  +tds[12].textContent.trim();
    bat.cs =  +tds[13].textContent.trim();
    bat.bb =  +tds[14].textContent.trim();
    bat.so =  +tds[15].textContent.trim();
    bat.hbp = +tds[22].textContent.trim();
    bat.tms = tds[26].textContent.trim();
    STATS.roster[id].bat = bat;
  }

  // Get team games from totals
  STATS.g = +document.getElementById('team_batting').getElementsByTagName(
      'tfoot')[0].getElementsByTagName('tr')[0].getElementsByTagName(
      'td')[3].textContent.trim();

  return STATS.roster;
}

function parsePit() {
  var i, pit, trs, tds, id, ip;
  trs = document.getElementById('team_pitching').getElementsByTagName(
      'tbody')[0].getElementsByTagName('tr');
      
  for (i=0; i<trs.length; i++) {
    pit = {};
    tds = trs[i].getElementsByTagName('td');
    id = tds[1].getElementsByTagName('a')[0].href;
    id = id.substring(id.length-12);
    pit.w =  +tds[3].textContent.trim();
    pit.l =  +tds[4].textContent.trim();
    pit.g =  +tds[7].textContent.trim();
    pit.gs = +tds[8].textContent.trim();
    pit.sv = +tds[12].textContent.trim();
    
    ip = +tds[13].textContent.trim();
    pit.ipo = Math.round(3*Math.floor(ip) + 10*(ip - Math.floor(ip)));
    pit.h =  +tds[14].textContent.trim();
    pit.er = +tds[16].textContent.trim();
    pit.hr = +tds[17].textContent.trim();
    pit.bb = +tds[18].textContent.trim();
    pit.so = +tds[20].textContent.trim();
    pit.tms = tds[31].textContent.trim();

    STATS.roster[id].pit = pit;
  }
  return STATS.roster;
}

function parseFld(pos) {
  var i, table, fld, trs, tds, id, ip;
  
  table = document.getElementById('team_fielding_by_' + pos);
  if (!table) {
    return false;
  } 
  trs = table.getElementsByTagName('tbody')[0].getElementsByTagName('tr');
      
  for (i=0; i<trs.length; i++) {
    fld = {};
    tds = trs[i].getElementsByTagName('td');
    id = tds[0].getElementsByTagName('a')[0].href;
    id = id.substring(id.length-12);
    fld.g =  +tds[1].textContent.trim();
    fld.po = +tds[3].textContent.trim();
    fld.a =  +tds[4].textContent.trim();
    fld.e =  +tds[5].textContent.trim();
    if (!STATS.roster[id].fld) {
      STATS.roster[id].fld = {};
    }
    STATS.roster[id].fld[pos] = fld;
  }
  return STATS.roster;
}

function padNum(num, size, prefix) {
  var padded = (prefix || "            ")+num;
  return padded.substring(padded.length-size);
}

function padName(name) {
  return (name.replace(',',", ") + "                  ").substring(0, 18);
}

function toSbsHit(id) {
  var e = 0, pos, fld = [], i, gamP = "";
  var player = STATS.roster[id];
  var sortFn = function (a, b) {
    return b.g - a.g;
  };
  
  if (player.fld) {
    for (pos in player.fld) {
      e += player.fld[pos].e;
      fld.push({
        pos: pos,
        g: player.fld[pos].g
      });
    }
  }
  fld.sort(sortFn);
  for (i=0; i<4 && i<fld.length; i++) {
    gamP = gamP + " " + padNum(fld[i].g, 3, "000") + "-" + POS_GAMP[POS[fld[i].pos]];
  }
  
  if (player.bat) {
    return [
      padNum(player.age, 2, "00"),
      "    ",
      padNum(POS[getPrime(id)] || 10, 2, "00"),
      (player.bat.tms.length > 5 ? "#" : " "),
      padName(player.name),
      padNum(player.bat.ab, 3),
      padNum(player.bat.h, 4),
      padNum(player.bat.db, 4),
      padNum(player.bat.tr, 4),
      padNum(player.bat.hr, 4),
      padNum(player.bat.bb, 4),
      padNum(player.bat.so, 4),
      padNum(player.bat.rbi, 4),
      padNum(player.b, 2),
      padNum(e, 4),
      padNum(player.bat.sb, 3),
      padNum(player.bat.cs, 3),
      padNum(player.bat.g, 4),
      gamP
    ].join('');
  } else {
    return padNum(player.age, 2, "00") + "    10 " + padName(player.name);
  }
}

function toSbsPit(id) {
  var player, era, t, gsF, h, ab, code, bat;
  player = STATS.roster[id];
  era = Math.round(player.pit.er / player.pit.ipo * 2700);
  era = (era > 999) ? 999 : era;
  gsF = player.pit.gs / player.pit.g; 
  h = (player.bat ? player.bat.h : 0) + 25 * (.105 + .035 * gsF)
  ab = (player.bat ? player.bat.ab : 0) + 25;
  if (h / ab > .225) {
    code = 'A';
  } else if (h / ab > .175) {
    code = 'B';
  } else if (h / ab > .125) {
    code = 'C';
  } else if (h / ab > .075) {
    code = 'D';
  } else {
    code = 'E';
  }

  if (player.bat && player.bat.ab + player.bat.bb > 10) {  
    bat = [
      padNum(player.bat.ab, 7),
      padNum(player.bat.h, 4),
      padNum(player.bat.hr, 3),
      padNum(player.bat.bb, 4),
      padNum(player.bat.so, 4),
    ].join('');
  } else {
    bat = ["  ", code].join('');  
  } 

  if (player.pit) {
    return [
      padNum(player.age, 2, "00"),
      "    01",
      (player.pit.tms.length > 5 ? "#" : " "),
      padName(player.name),
      padNum(Math.round(player.pit.ipo/3), 3),
      padNum(player.pit.h, 4),
      padNum(player.pit.hr, 12),
      padNum(player.pit.bb, 4),
      padNum(player.pit.so, 4),
      padNum(era, 4),
      " ",
      getThrowingArm(id),
      padNum(player.pit.w, 4),
      padNum(player.pit.l, 3),
      padNum(player.pit.sv, 3),
      padNum(player.pit.g, 4),
      padNum(player.pit.gs, 4),
      bat
    ].join('');
  } else {
    return padNum(player.age, 2, "00") + "    01 " + padName(player.name);
  }
}

function getPrime(id) {
  var player, max, top, pos;
  player = STATS.roster[id];
  max = 0;
  top = "DH";
  if (player.fld) {
    for (pos in player.fld) {
      if (player.fld[pos].g > max) {
        max = player.fld[pos].g;
        top = pos;
      }
    }    
    return top;
  }

};

function getThrowingArm(id) {
  var player, b, t;
  player = STATS.roster[id];
  b = player.b.charAt(0);
  t = player.t.charAt(0);
  if (t === 'R') {
    if (b === 'L' || b === 'S') {
      return 'r';
    } else {
      return 'R';    
    }
  } else if (t === 'L') {
    if (b === 'R') {
      return 'l';
    } else {
      return 'L';
    }    
  } else {
    return '?'
  }

};

function sortRoster() {
  var lineup = [], bench = [], pitching = [], inactive = [];
  var id, player, filled, i, pos;
  var rotation, closer, bullpen, topPlayer, topPos, topG;
  var paMin = STATS.g / 162 * 50, ipoMin = STATS.g / 162 * 75; 
  
  // Sort functions go here
  var sortBench = function(a, b) {
    var playerA = STATS.roster[a], playerB = STATS.roster[b];
    var scoreA = playerA.bat.ab + playerA.bat.bb + playerA.bat.g;
    var scoreB = playerB.bat.ab + playerB.bat.bb + playerB.bat.g;
    return scoreB - scoreA; 
  };

  var sortRotation = function(a, b) {
    var playerA = STATS.roster[a], playerB = STATS.roster[b];
    var scoreA = playerA.pit.gs + playerA.pit.w;
    var scoreB = playerB.pit.gs + playerB.pit.w;
    return scoreB - scoreA; 
  };

  var sortCloser = function(a, b) {
    var playerA = STATS.roster[a], playerB = STATS.roster[b];
    var scoreA = playerA.pit.sv;
    var scoreB = playerB.pit.sv;
    return scoreB - scoreA; 
  };

  var sortReliever = function(a, b) {
    var playerA = STATS.roster[a], playerB = STATS.roster[b];
    var scoreA = playerA.pit.g - playerB.pit.gs * .98;
    var scoreB = playerB.pit.g - playerB.pit.gs * .98;
    return scoreB - scoreA; 
  };
  
  var sortInactive = function(a, b) {
    var playerA = STATS.roster[a], playerB = STATS.roster[b];
    var scoreA, scoreB;
    if (getPrime(a) === "P") {
      if (getPrime(b) !== "P") {
        return 1;
      } else {
        scoreA = playerA.pit && playerA.pit.ipo;
        scoreB = playerB.pit && playerB.pit.ipo;
      }
    } else {
      if (getPrime(b) === "P") {
        return -1;
      } else {
        scoreA = playerA.bat && playerA.bat.g;
        scoreB = playerB.bat && playerB.bat.g;
      }
    }
    return scoreB - scoreA; 
  };
  
  // Loop over each player, determining whether to put them on bench, pitching,
  // or inactive.
  for (id in STATS.roster) {
    player = STATS.roster[id];
    if (player.pit && player.pit.ipo >= ipoMin) {
      pitching.push(id);
      if (player.bat && player.bat.g - player.pit.g > 5) {
        bench.push(id);
      }
      
    } else if (player.bat && player.bat.ab + player.bat.bb >= paMin) {
      bench.push(id);
    } else {
      inactive.push(id);    
    }
  }
  
  // Then, pick the rotation and closer spots.
  pitching.sort(sortCloser);
  closer = pitching.splice(0, 1);
  pitching.sort(sortRotation);
  rotation = pitching.splice(0, 5);
  pitching.sort(sortReliever);
  bullpen = pitching.splice(0);
  pitching = rotation.concat(closer).concat(bullpen);
  
  bench.sort(sortBench);
  inactive.sort(sortInactive);
  
  // Then, pick the starting 8 (or 9) and sort the lineup.
  // SBS method: 3:OPS, 4:RBI/PA, 1-2:SB/PA, 5-9:Slg%
  // TODO: Repeat this 8-9 times:
  /*filled = {};
  while (true) {
    topPos = "";
    topG = 0;
    for (i = 0; i < bench.length; i++) {
      id = bench[i];
      player = STATS.roster[id];
      for (pos in player.fld) {
        if (!filled[pos] && player.fld[pos].g > topG) {
          topPos = pos;
          topG = player.fld[pos].g;
          topPlayer = id;        
        }
      }        
    }
    if (topG > 0) {
      lineup.push(topPlayer);
      bench.splice(bench.indexOf(topPlayer), 1);
      filled[topPos] = true;
    } else {
      break;
    }
  }*/

  STATS.lineup = lineup;
  STATS.pitching = pitching;
  STATS.bench = bench;
  STATS.inactive = inactive;
}

function dumpDat() {
  var teamFilter = function (team) {
    var words = team.split(' ');
    if (words.length > 2) {
      return [words[0], ' ', words[1]].join('');
    }
    return words[0];
  };

  var buffer, id, player, i;
  var lg = "?", div = " ", year = "????", team = "Team        ";
  var h1 = document.getElementsByTagName('h1')[0];
  year = h1.textContent.substring(0, 4);
  team = teamFilter(h1.textContent.substring(5));
  team = (team + "            ").substring(0, 12);
   
  //var infoBox = document.getElementById('info_box');
  //var p = infoBox.getElementsByTagName('p');
  //var league = p.getElementsByTagName('a')[1].textContent.substring(5);
  //lg = lgCodes[league] || league.substring(0, 1).toLowerCase();
  
  buffer = ["*", lg, "       ", div, year, " ", team, 
      " AB Hit  2B  3B  HR  BB  SO RBI B ERR SB CS Gam Gam-P Gam-P Gam-P Gam-P\n"].join('');
  for (i=0; i<STATS.lineup.length; i++) {
    buffer += toSbsHit(STATS.lineup[i]) + "\n";
  }
  if (STATS.lineup.length < 9) {
    buffer += "00    01\n";
  }

  buffer += "*Pitching                  Inn Hit          HR  BB  SO ERA T   W  L  S Gam  GS     AB Hit HR  BB  SO\n";

  for (i=0; i<STATS.pitching.length; i++) {
    buffer += toSbsPit(STATS.pitching[i]) + "\n";
  }

  buffer += "*Bench                      AB Hit  2B  3B  HR  BB  SO RBI B ERR SB CS Gam Gam-P Gam-P Gam-P Gam-P\n";
  for (i=0; i<STATS.bench.length; i++) {
    buffer += toSbsHit(STATS.bench[i]) + "\n";
  }

  buffer += "###\n";
  for (i=0; i<STATS.inactive.length; i++) {
    id = STATS.inactive[i];
    if (getPrime(id) === "P") { 
      buffer += toSbsPit(id) + "\n";
    } else {
      buffer += toSbsHit(id) + "\n";
    }
  }
  return buffer;
}

function popDiv() {
  var div = document.getElementById('dat');
  if (!div) {
    var div = document.createElement("pre");
    var body = document.getElementsByTagName('body')[0];
    div.id = "dat";
    body.appendChild(div);
  
    div.style.position = 'fixed';
    div.style.width = div.style.height = '80%';
    div.style.top = div.style.left = '10%';
    div.style.border = "2px solid";
    div.style.backgroundColor = 'lightGreen';
    div.style.opacity = '0.9';
    div.style.overflow = 'scroll';
    div.style.textAlign = 'left';
    div.style.padding = '5px';
  }

  div.innerHTML = dumpDat();
  
  return div;
}

function log(string) {
  if (typeof console == "object") {
    console.log(string);
  }
}

parseRoster();
parseBat();
parsePit();
parseFld('C');
parseFld('1B');
parseFld('2B');
parseFld('3B');
parseFld('SS');
if (parseFld('LF')) {
  parseFld('CF');
  parseFld('RF');
} else {
  parseFld('OF');
}
parseFld('P');
//adjustForDH(.75);
try {
  sortRoster();
} catch (e) {
  alert("Error in sortRoster")
}
popDiv();
